package it.unica.informatica.enotes;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

import it.unica.informatica.enotes.database.DatabaseAdapter;
import it.unica.informatica.enotes.database.DatabaseHelper;
import it.unica.informatica.enotes.notes.Note;
import it.unica.informatica.enotes.adapter.NoteListAdapter;
import it.unica.informatica.enotes.manager.NotesManager;

/**
 * This activity provides all operations related to visualization and search of notes.
 *
 * @author Massimiliano Meles
 * @version 1.0
 */
public class MainScreenActivity extends ActionBarActivity {


    /* *****************************************************************************************
    *                             VARIABLES AND CONSTANTS                                      *
    * ******************************************************************************************/


    /*Variables used to launch intents*/
   public static final int ACTIVITY_EDIT = 1;
   public static final int ACTIVITY_CREATE = 2;
   public final static String NOTE_ID = "it.unica.informatica.OPEN_NOTE_BY_ID";

   /*Variables used to hide/show textview/linearlayout */
   public static final int MODE_SEARCH = 1;
   public static final int MODE_MAIN = 2;

   private static boolean searched;
   private static Menu menu;

   private DatabaseAdapter databaseAdapter;
   private NoteListAdapter adapter;
   private ArrayList<Note> notes;


    /* *******************************************************************************************
    *                                  ACTIVITY LIFECYCLE METHODS                                *
    * *******************************************************************************************/


   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main_screen);

      //Set and enabled action bar log
      getSupportActionBar().setDisplayShowHomeEnabled(true);
      getSupportActionBar().setIcon(R.drawable.ic_action_note);

      //No search done at start of activity
      searched = false;

      //Initialization of note list
      notes = new ArrayList<Note>();

      //Initialization of adapter to visualize ListView of notes
      ListView notesListView = (ListView) findViewById(R.id.notesListView);
      adapter = new NoteListAdapter(this, notes);
      notesListView.setAdapter(adapter);

      //Opening of database istance
      databaseAdapter = new DatabaseAdapter(getApplicationContext());
      databaseAdapter.open();


      //Set a listener for the click action on a note
      notesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> adapter, final View component, int pos, long id) {
            Note note = (Note) adapter.getItemAtPosition(pos);
            Intent intent = new Intent(getApplicationContext(), NotesActivity.class);
            intent.putExtra(NOTE_ID, note.getId());
            startActivityForResult(intent, ACTIVITY_EDIT);
         }
      });
   }

   @Override
   protected void onStart() {
      super.onStart();

      if (searched) {
         //Disable focus on searchView when return from NotesActivity, the change on focus force the call to onFocusChange in searchView listener
         //and this show again all notes in activity
         MenuItem searchItem = menu.findItem(R.id.action_search);
         SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
         searchView.setQuery("", false);
         searchView.setIconified(true);
      } else {
         //All notes in the Database inserted in the ArrayList notes
         NotesManager.fetchAllNotes(databaseAdapter, notes);
         setVisibility(MODE_MAIN, null);
      }


   }

   @Override
   protected void onResume() {
      super.onResume();

      //Each time the Activity gain focus, notify a possible change on the content of notes (E.g after a search)
      adapter.notifyDataSetChanged();
   }


    /* *******************************************************************************************
    *                                  ACTION BAR AND OTHERS METHODS                             *
    * *******************************************************************************************/



   @Override
   public void onBackPressed() {
        /*The action associated with back is the standard one if no search is performed.
          If a search is performed and back is pressed, all notes are loaded and the activity show again the main layout with all notes
         */

      if (searched) {
         NotesManager.fetchAllNotes(databaseAdapter, notes);

         //Visibility management of Views of the activity
         setVisibility(MODE_MAIN, null);

         adapter.notifyDataSetChanged();

         Toast.makeText(this, R.string.back_to_full_list,
                 Toast.LENGTH_SHORT).show();

         searched = false;

         ( findViewById(R.id.nResults) ).setVisibility(View.GONE);
      } else {
         super.onBackPressed();
      }

   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      //Store reference to menu Object
      MainScreenActivity.menu = menu;

      //Define menu layout
      final MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.menu_main_screen, menu);

      //Creation of a SearchManager and binding of it with SearchView
      SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
      MenuItem searchItem = menu.findItem(R.id.action_search);
      SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
      searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

      //Set a listener for the change of the focus in the SearchView (it's used to set visibility of Add Button, to provide space for searchbar)
      searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
         @Override
         public void onFocusChange(View view, boolean queryTextFocused) {
            MainScreenActivity.menu.findItem(R.id.action_add_note).setVisible(!queryTextFocused);
            if (!queryTextFocused) {
               supportInvalidateOptionsMenu();
               if (searched) {
                  NotesManager.fetchAllNotes(databaseAdapter, notes);

                  //Visibility management of Views of the activity
                  setVisibility(MODE_MAIN, null);

                  adapter.notifyDataSetChanged();

                  Toast.makeText(getApplicationContext(), R.string.back_to_full_list,
                          Toast.LENGTH_SHORT).show();

                  searched = false;

                  ( findViewById(R.id.nResults) ).setVisibility(View.GONE);
               }
            }

         }
      });


      return true;
   }

   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      int id = item.getItemId();

      //Manage selection of one item on the actionBar (Search is managed in different way)
      switch (id) {
         case R.id.action_add_note:
            Intent intent = new Intent(this, NotesActivity.class);
            startActivityForResult(intent, ACTIVITY_CREATE);
      }

      return super.onOptionsItemSelected(item);
   }

   /*The ovveride of this method is necessary to manage SingleTop LaunchMode */
   @Override
   protected void onNewIntent(Intent intent) {
      setIntent(intent);
      handleIntent(intent);
   }


   /**********************************************************************************************
    *                                  SUPPORT METHODS                                           *
    **********************************************************************************************/

   /**
    * The method has the purpose to handle intents from the SearcView
    *
    * @param intent The intent to handle
    */
   private void handleIntent(Intent intent) {

      // Handles a click on a search suggestion
      if (Intent.ACTION_VIEW.equals(intent.getAction())) {

         //Get uri from the intent
         Uri uri = getIntent().getData();

         //NoteDatabaseProvider uses the uri to get the tag selected
         Cursor cursor = getContentResolver().query(uri, null, null, null, null);

         //If the query has a result, search for the tag selected in the Database, then search for all notes with that tag
         if (cursor == null) {
            finish();
         } else {
            cursor.moveToFirst();
            int wIndex = cursor.getColumnIndexOrThrow(DatabaseHelper.KEY_TAG);
            String tag = cursor.getString(wIndex);
            cursor.close();
            MenuItem searchItem = menu.findItem(R.id.action_search);
            SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
            searchView.setQuery(tag, true);


         }
         // Handles a click on search button on virtual keyboard
      } else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
         //Search for the tag digited in the Database, then search for all notes with that tag
         String query = intent.getStringExtra(SearchManager.QUERY);
         showResults(query);
      }
      //A search was performed, so set the flag to show correct Textviews/LinearLayouts
      searched = true;
   }

   /**
    * The method has the purpose to handle intents from the SearcView
    *
    * @param query The tag to include in the search
    */
   private void showResults(String query) {

      //Load all the notes with that tag
      NotesManager.fetchNoteByTag(databaseAdapter, notes, query);

      //Set a string with correct spelling of Plurals for more than one result
      String countString = getResources().getQuantityString(R.plurals.results,
              notes.size(), notes.size());

      //Visibility management of Views of the activity
      setVisibility(MODE_SEARCH, countString);

      //Update ListView
      adapter.notifyDataSetChanged();
   }

   /**
    * The method set visibility from TextView/Layout
    *
    * @param mode        The mode indicate witch view to show
    * @param countString The string to insert in textView (number of results)
    */
   private void setVisibility(int mode, String countString) {

      //Get references from all View
      TextView nResults = (TextView) findViewById(R.id.nResults);
      TextView noNotes = (TextView) findViewById(R.id.noNotes);
      LinearLayout ll1 = (LinearLayout) findViewById(R.id.ll1);

      switch (mode) {
         case MODE_SEARCH:
            nResults.setText(countString);
            nResults.setVisibility(View.VISIBLE);
            if (notes.size() > 0) {
               noNotes.setVisibility(View.GONE);
               ll1.setVisibility(View.VISIBLE);
            } else {
               noNotes.setVisibility(View.VISIBLE);
               ll1.setVisibility(View.GONE);
            }
            break;
         case MODE_MAIN:
            nResults.setVisibility(View.GONE);
            if (notes.size() > 0) {
               noNotes.setVisibility(View.GONE);
               ll1.setVisibility(View.VISIBLE);
            } else {
               noNotes.setVisibility(View.VISIBLE);
               ll1.setVisibility(View.GONE);
            }
      }
   }
}